<template>
  <vxe-pulldown ref="pullDown">
    <template>
      <slot name="component">
        <vxe-input
            ref="xInput"
            v-model="inputValue"
            v-bind="$attrs"
            v-on="$listeners"
            @keyup="keyupEvent"
            @focus="focusEvent"
            @suffix-click="suffixClick"/>
      </slot>
    </template>
    <template v-slot:dropdown>
      <div class="pull-down">
        <vxe-grid
            ref="xGrid"
            v-bind="$attrs"
            :pager-config="tablePage"
            :data="tableData"
            :columns="tableColumn"
            :keyboard-config="{isArrow: true, isEnter: true}"
            highlight-hover-row
            highlight-current-row
            header-align="center"
            align="center"
            show-overflow
            auto-resize
            height="auto"
            v-on="$listeners"
            @keydown="keyDownEvent"
            @page-change="handlePageChange"
            @cell-dblclick="cellClickEvent"/>
      </div>
    </template>
  </vxe-pulldown>
</template>

<script>
  import request from '@/utils/request'

  export default {
    name: 'PullDownSelect',
    props: {
      label: {
        type: String,
        default: ''
      },
      value: {
        type: String,
        default: ''
      },
      props: {
        type: Object,
        default() {
          return {
            label: 'label',
            value: 'value'
          }
        }
      },
      tableColumn: {
        type: Array,
        default() { return [] }
      },
      url: {
        type: Object,
        default: () => {
          return {
            path: '',
            params: ''
          }
        },
        required: true
      }
    },
    data() {
      return {
        inputValue: '',
        loading: false,
        tablePage: {
          total: 0,
          currentPage: 1,
          pageSize: 20,
          pageSizes: [10, 20, 50],
          perfect: true
        },
        tableData: [],
        row: {}
      }
    },
    watch: {
      row() {
        this.$emit('update:value', this.row[this.props.value])
        this.$emit('update:label', this.row[this.props.label])
      },
      value() {
        this.$emit('update:value', this.value)
      },
      label() {
        this.inputValue = this.label
        this.$emit('update:label', this.label)
      }
    },
    mounted() {
      const postData = {}
      postData[this.props.value] = this.value
      this.loadData(postData, () => {
        this.row = this.tableData[0]
      })
    },
    methods: {
      loadData(query, callback) {
        const params = Object.assign({ page: this.tablePage.currentPage, limit: this.tablePage.pageSize }, query, this.url.params)
        if (this.url) {
          return request({
            url: this.url.path,
            method: 'get',
            params: params
          }).then((response) => {
            this.tablePage.total = response.result.total
            this.tableData = response.result.items
            if (callback) callback()
          })
        }
      },
      focusEvent() {
        this.$refs.pullDown.showPanel()
        this.loadData()
      },
      keyupEvent({ $event }) {
        // ArrowDown
        if ($event.keyCode === 40) {
          const row = this.tableData[0]
          this.$refs.xGrid.setCurrentRow(row)
          this.$refs.xInput.blur()
          this.$refs.xGrid.focus()
        } else {
          const { inputValue } = this
          const that = this
          setTimeout(() => {
            const query = {}
            query[that.props.label] = inputValue
            query[that.props.value] = inputValue
            that.loadData(query)
          }, 300)
        }
      },
      keyDownEvent({ $event }) {
        if ($event.keyCode === 13) {
          const row = this.$refs.xGrid.getCurrentRecord()
          this.cellClickEvent({ row })
        }
      },
      suffixClick() {
        this.$refs.pullDown.togglePanel()
      },
      cellClickEvent({ row }) {
        this.row = row
        this.inputValue = row[this.props.label]
        this.$refs.pullDown.hidePanel()
      },
      handlePageChange({ currentPage, pageSize }) {
        this.tablePage.currentPage = currentPage
        this.tablePage.pageSize = pageSize
        this.loadData()
      }
    }
  }
</script>

<style scoped>
  .pull-down {
    width: 400px;
    height: 300px;
    background-color: #fff;
    border: 1px solid #dcdfe6;
    z-index: 10000;
    box-shadow: 0 0 6px 2px rgba(0, 0, 0, 0.1);
  }
</style>
